<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.1">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/%E6%AD%A6%E6%B1%8932x32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/%E6%AD%A6%E6%B1%8916x16.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib1/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="/lib1/pace/pace-theme-center-simple.min.css">
  <script src="/lib1/pace/pace.min.js"></script>

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"example.com","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="概述初始化场景场景scene是一个容器，主要用于保存、跟踪所要渲染得物体和所使用的光源。 摄像机camera决定了能在场景看到什么。 渲染器renderer对象会基于摄像机的角度来计算场景对象在浏览器会渲染册灰姑娘什么样子。 轴与平面axes、plane。 12345678910111213141516171819202122232425262728293031323334353637383940">
<meta property="og:type" content="article">
<meta property="og:title" content="three.js初学">
<meta property="og:url" content="http://example.com/2021/09/16/webgl/three.js%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/index.html">
<meta property="og:site_name" content="Technological Blog">
<meta property="og:description" content="概述初始化场景场景scene是一个容器，主要用于保存、跟踪所要渲染得物体和所使用的光源。 摄像机camera决定了能在场景看到什么。 渲染器renderer对象会基于摄像机的角度来计算场景对象在浏览器会渲染册灰姑娘什么样子。 轴与平面axes、plane。 12345678910111213141516171819202122232425262728293031323334353637383940">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2021-09-16T04:18:39.000Z">
<meta property="article:modified_time" content="2021-11-03T08:22:12.986Z">
<meta property="article:author" content="Li Yudong">
<meta property="article:tag" content="three.js">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://example.com/2021/09/16/webgl/three.js%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>three.js初学 | Technological Blog</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">Technological Blog</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">IT小白的成长之旅</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="tags fa-fw"></i>标签<span class="badge">18</span></a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="th fa-fw"></i>分类<span class="badge">14</span></a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="archive fa-fw"></i>归档<span class="badge">95</span></a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

  <a href="https://github.com/tiarmor1" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/09/16/webgl/three.js%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/author.jpg">
      <meta itemprop="name" content="Li Yudong">
      <meta itemprop="description" content="">
    </span>
    
    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Technological Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          three.js初学
        </h1>
    
        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>
    
              <time title="创建时间：2021-09-16 12:18:39" itemprop="dateCreated datePublished" datetime="2021-09-16T12:18:39+08:00">2021-09-16</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-11-03 16:22:12" itemprop="dateModified" datetime="2021-11-03T16:22:12+08:00">2021-11-03</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/webgl/" itemprop="url" rel="index"><span itemprop="name">webgl</span></a>
                </span>
            </span>
    
          
    
        </div>
      </header>
    
    
    
    
    <div class="post-body" itemprop="articleBody">
    
      
        <h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><h2 id="初始化场景"><a href="#初始化场景" class="headerlink" title="初始化场景"></a>初始化场景</h2><p>场景scene是一个容器，主要用于保存、跟踪所要渲染得物体和所使用的光源。</p>
<p>摄像机camera决定了能在场景看到什么。</p>
<p>渲染器renderer对象会基于摄像机的角度来计算场景对象在浏览器会渲染册灰姑娘什么样子。</p>
<p>轴与平面axes、plane。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">init</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// create a scene, that will hold all our elements such as objects, cameras and lights.</span></span><br><span class="line">    <span class="keyword">var</span> scene = <span class="keyword">new</span> THREE.Scene();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// create a camera, which defines where we're looking at.</span></span><br><span class="line">    <span class="keyword">var</span> camera = <span class="keyword">new</span> THREE.PerspectiveCamera(<span class="number">45</span>, <span class="built_in">window</span>.innerWidth / <span class="built_in">window</span>.innerHeight, <span class="number">0.1</span>, <span class="number">1000</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// create a render and set the size</span></span><br><span class="line">    <span class="keyword">var</span> renderer = <span class="keyword">new</span> THREE.WebGLRenderer();</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">    最初定义最需要的三要素：场景、摄像机、渲染器；</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    renderer.setClearColor(<span class="keyword">new</span> THREE.Color(<span class="number">0x000000</span>));</span><br><span class="line">    <span class="comment">//设置背景颜色与场景大小</span></span><br><span class="line">    renderer.setSize(<span class="built_in">window</span>.innerWidth, <span class="built_in">window</span>.innerHeight);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// show axes in the screen</span></span><br><span class="line">    <span class="comment">//定义并添加坐标轴与平面，在three.js中，我们通过创建材质对象来设置平面的外观。</span></span><br><span class="line">    <span class="keyword">var</span> axes = <span class="keyword">new</span> THREE.AxesHelper(<span class="number">20</span>);</span><br><span class="line">    scene.add(axes);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// create the ground plane</span></span><br><span class="line">    <span class="keyword">var</span> planeGeometry = <span class="keyword">new</span> THREE.PlaneGeometry(<span class="number">60</span>, <span class="number">20</span>);</span><br><span class="line">    <span class="keyword">var</span> planeMaterial = <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;</span><br><span class="line">        color: <span class="number">0xAAAAAA</span></span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">var</span> plane = <span class="keyword">new</span> THREE.Mesh(planeGeometry, planeMaterial);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// rotate and position the plane</span></span><br><span class="line">    plane.rotation.x = <span class="number">-0.5</span> * <span class="built_in">Math</span>.PI;</span><br><span class="line">    plane.position.set(<span class="number">15</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// add the plane to the scene</span></span><br><span class="line">    scene.add(plane);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// create a cube</span></span><br><span class="line">    <span class="keyword">var</span> cubeGeometry = <span class="keyword">new</span> THREE.BoxGeometry(<span class="number">4</span>, <span class="number">4</span>, <span class="number">4</span>);</span><br><span class="line">    <span class="keyword">var</span> cubeMaterial = <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;</span><br><span class="line">        color: <span class="number">0xFF0000</span>,</span><br><span class="line">        wireframe: <span class="literal">true</span></span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">var</span> cube = <span class="keyword">new</span> THREE.Mesh(cubeGeometry, cubeMaterial);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// position the cube</span></span><br><span class="line">    cube.position.set(<span class="number">-4</span>, <span class="number">3</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// add the cube to the scene</span></span><br><span class="line">    scene.add(cube);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// create a sphere</span></span><br><span class="line">    <span class="keyword">var</span> sphereGeometry = <span class="keyword">new</span> THREE.SphereGeometry(<span class="number">4</span>, <span class="number">20</span>, <span class="number">20</span>);</span><br><span class="line">    <span class="keyword">var</span> sphereMaterial = <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;</span><br><span class="line">        color: <span class="number">0x7777FF</span>,</span><br><span class="line">        wireframe: <span class="literal">true</span></span><br><span class="line">    &#125;);</span><br><span class="line">    <span class="keyword">var</span> sphere = <span class="keyword">new</span> THREE.Mesh(sphereGeometry, sphereMaterial);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// position the sphere</span></span><br><span class="line">    sphere.position.set(<span class="number">20</span>, <span class="number">4</span>, <span class="number">2</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// add the sphere to the scene</span></span><br><span class="line">    scene.add(sphere);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// position and point the camera to the center of the scene</span></span><br><span class="line">    <span class="comment">//设置摄像机的位置与其观察的方位</span></span><br><span class="line">    camera.position.set(<span class="number">-30</span>, <span class="number">40</span>, <span class="number">30</span>);</span><br><span class="line">    camera.lookAt(scene.position);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// add the output of the renderer to the html element</span></span><br><span class="line">    <span class="built_in">document</span>.getElementById(<span class="string">"webgl-output"</span>).appendChild(renderer.domElement);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// render the scene</span></span><br><span class="line">    renderer.render(scene, camera);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="材质、光源与阴影"><a href="#材质、光源与阴影" class="headerlink" title="材质、光源与阴影"></a>材质、光源与阴影</h2><p>光源spotLight定义光源位置，并从其位置照射场景；通过将castShadow属性设置为true，three.js的阴影功能被启用。</p>
<p>材质Material用来定义物体的颜色以及视觉效果程度，有的材质也会对光源产生反应。</p>
<p>渲染阴影需要消耗大量性能，因此three.js默认不会渲染阴影，首先需要设置shdowMapEnabled属性为true，然后需要明确指定哪个物体投射阴影，哪个物体接受阴影，相应的receiveShadow、castShadow属性设置为true。同时，我们需要定义能够产生阴影的光源，通过spotlight.castshadow属性来设置。</p>
<h2 id="动画"><a href="#动画" class="headerlink" title="动画"></a>动画</h2><p>动画实现的关键是：如何在特定的事件间隔重新渲染场景。在H5相关的API出现之前，是通过setInterval方法来实现的，但该方法并没有与屏幕的刷新同步，将导致高的CPU使用率与性能不良。</p>
<h3 id="requestAnimationFrame"><a href="#requestAnimationFrame" class="headerlink" title="requestAnimationFrame"></a>requestAnimationFrame</h3><p> requestAnimationFrame该函数为稳定而连续的渲染场景提供了良好的解决方案；通过该函数，你可以向浏览器提供一个回调函数，无须定义回调间隔，浏览器会自行决定最佳的回调时机。</p>
<p>你需要做的是在这个回调函数里完成一帧绘制操作，将剩下工作交给浏览器。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">init</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">	<span class="built_in">document</span>.getElementById(<span class="string">"webgl-output"</span>).appendChild(renderer.domElement);</span><br><span class="line">    <span class="comment">//在场景创建完成后，不再调用renderer.render()方法，而是调用renderScene()来启动动画</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">// call the render function</span></span><br><span class="line">    <span class="keyword">var</span> step = <span class="number">0</span>;</span><br><span class="line">    renderScene();</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">renderScene</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        stats.update();</span><br><span class="line">        <span class="comment">// rotate the cube around its axes</span></span><br><span class="line">        cube.rotation.x += <span class="number">0.02</span>;</span><br><span class="line">        cube.rotation.y += <span class="number">0.02</span>;</span><br><span class="line">        cube.rotation.z += <span class="number">0.02</span>;</span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">        这里我们每次调用renderScene()时让物体每个方向的rotation属性+0.02</span></span><br><span class="line"><span class="comment">        */</span></span><br><span class="line">        <span class="comment">// bounce the sphere up and down</span></span><br><span class="line">        step += <span class="number">0.04</span>;</span><br><span class="line">        sphere.position.x = <span class="number">20</span> + (<span class="number">10</span> * (<span class="built_in">Math</span>.cos(step)));</span><br><span class="line">        sphere.position.y = <span class="number">2</span> + (<span class="number">10</span> * <span class="built_in">Math</span>.abs(<span class="built_in">Math</span>.sin(step)));</span><br><span class="line">        <span class="comment">// render using requestAnimationFrame</span></span><br><span class="line">        requestAnimationFrame(renderScene);</span><br><span class="line">        <span class="comment">//这里我们将递归执行其本身，从而让动画一直执行</span></span><br><span class="line">        renderer.render(scene, camera);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>对于动画的监控，我们可以使用Stats.js来实时监测帧数；使用dat.GUI简化实验流程。</p>
<h1 id="基本组件"><a href="#基本组件" class="headerlink" title="基本组件"></a>基本组件</h1><h2 id="场景"><a href="#场景" class="headerlink" title="场景"></a>场景</h2><p>一个场景想要显示任何东西，需要最少有以下的组件：摄像机（决定屏幕上哪些东西需要渲染）、光源（决定材质如何显示以及用于产生阴影）、对象（摄像机透视图里主要渲染对象）、渲染器（基于摄像机和场景提供的信息，调用底层API执行真正的场景绘制工作）。</p>
<p>THREE.Scene:环境；THREE.Mesh：平面；</p>
<p>THREE.SpotLight：聚光灯光源；THREE.AmbientLight：环境光；</p>
<p>THREE.Camera：摄像机；</p>
<p>场景相关方法有：</p>
<p>THREE.Scene.Add：用于向场景中添加对象；THREE.Scene.Remove：用于移除场景中的对象；</p>
<p>THREE.Scene.children：用于获取场景中所有的子对象列表；THREE.Scene.getObjectByName：利用name属性，用于获取场景中特定的对象.</p>
<p>THREE.Scene.traverse()：该方法可以将一个方法作为参数传入函数，这个传递来的方法会在每一个子对象上执行。由于Scene存储的是对象树，因此相当于递归遍历树，会在所有子对象上执行，直至遍历完场景中的所有对象为止。</p>
<p>雾化效果：THREE.Scene.fog属性，使得场景中的物体离摄像机越远就会变得越模糊；此时雾化效果是线性增强的。THREE.Scene.FogExp2属性：此时雾化效果是随距离呈指数增长的。</p>
<p>THREE.Scene.overrideMaterial属性：当设置该属性后，场景中所有物体都会使用该属性指向的材质。</p>
<h2 id="物体"><a href="#物体" class="headerlink" title="物体"></a>物体</h2><p>几何体：THREE.Geometry。</p>
<p>当我们使用Three.js提供的几何体时，不需要自己定义顶点与面，只要定义长宽高就可由引擎正确创建，当然，也可以调用Geometry.vertices定义顶点，Geometry.Faces定义面。</p>
<p>clone方法：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">this</span>.clone = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">          <span class="keyword">var</span> clonedGeometry = mesh.children[<span class="number">0</span>].geometry.clone();</span><br><span class="line">          <span class="keyword">var</span> materials = [</span><br><span class="line">              <span class="keyword">new</span> THREE.MeshLambertMaterial(&#123;<span class="attr">opacity</span>: <span class="number">0.8</span>, <span class="attr">color</span>: <span class="number">0xff44ff</span>, <span class="attr">transparent</span>: <span class="literal">true</span>&#125;),</span><br><span class="line">              <span class="keyword">new</span> THREE.MeshBasicMaterial(&#123;<span class="attr">color</span>: <span class="number">0x000000</span>, <span class="attr">wireframe</span>: <span class="literal">true</span>&#125;)</span><br><span class="line">          ];</span><br><span class="line"></span><br><span class="line">          <span class="keyword">var</span> mesh2 = THREE.SceneUtils.createMultiMaterialObject(clonedGeometry, materials);</span><br><span class="line">    	<span class="comment">//利用createMultiMaterialObject方法将多个材质合成后，生成克隆后的对象。</span></span><br><span class="line">          mesh2.children.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">              e.castShadow = <span class="literal">true</span></span><br><span class="line">          &#125;);</span><br><span class="line">    	<span class="comment">//为该组中所有子对象添加阴影</span></span><br><span class="line">          mesh2.translateX(<span class="number">5</span>);</span><br><span class="line">          mesh2.translateZ(<span class="number">5</span>);</span><br><span class="line">          mesh2.name = <span class="string">"clone"</span>;</span><br><span class="line">          scene.remove(scene.getChildByName(<span class="string">"clone"</span>));</span><br><span class="line">          scene.add(mesh2);</span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure>

<p>网格物体对象的常见属性值：</p>
<p>position:该属性决定对象相对于父对象的位置，通常父对象为THREE.Scene对象或THREE.Object3D。</p>
<p>rotation:该属性可以设置绕每个轴的旋转弧度，其有rotateX、rotateY、rotateZ来设置相对特定轴的旋转弧度。在数学上旋转一周的弧度制为2Π。 </p>
<p>scale:通过该属性可沿着x、y、z轴来缩放对象。</p>
<p>visible：该属性设置为false时，不会渲染至场景中。</p>
<h2 id="摄像机"><a href="#摄像机" class="headerlink" title="摄像机"></a>摄像机</h2><p>透视投影摄像机：生成透视视图，离摄像机越远的物体，其渲染的尺寸就越小。THREE.PerspectiveCamera</p>
<p>正交投影摄像机：所有立方体被渲染出的尺寸都是一样的，对象相对于摄像机的距离对渲染的结果没有影响。THREE.OrthographicCamera。</p>
<p>透视投影摄像机的结果更贴近于真实世界。</p>
<p>THREE.PerspectiveCamera：透视投影摄像机的属性如下：使用透视摄像机时相当于是从一点发出的摄像视窗。</p>
<p>fov：表示视场，这是摄像机啊中能看到的那部分场景；人类的视场为180。</p>
<p>aspect：长宽比，这是渲染结果的横向尺寸和纵向尺寸的比值，由于一般使用窗口作为输出界面，因此使用的是窗口长宽比。</p>
<p>near：近面面积，从距离摄像机多近的距离则开始渲染；</p>
<p>far：远面面积，定义了摄像机从它所处的位置能够看多远。设的较小则有部分场景不被渲染，设的较大则会影响渲染性能。</p>
<p>zoom：变焦，使用该属性可放大、缩小场景。</p>
<p>THREE.OrthographicCamera：正交投影摄像机，相当于是从一个面平行发出的摄像视窗。</p>
<p>left、right、top、bottom:可视渲染范围的边界设置。</p>
<p>near、far：近面、远面面积。</p>
<p>zoom：变焦。</p>
<p>Camera.lookat()方法可以让摄像机指向某一点，或者传入某物体的position，则可让摄像机追随该物体。</p>
<h1 id="光源"><a href="#光源" class="headerlink" title="光源"></a>光源</h1><p>webGL本身并不支持光源，如果不使用three.js则需要自己写WebGL着色器程序。</p>
<p>Three.js中光源很多，每一种都有不同的用法</p>
<h2 id="基础光源"><a href="#基础光源" class="headerlink" title="基础光源"></a>基础光源</h2><h3 id="基本光源"><a href="#基本光源" class="headerlink" title="基本光源"></a>基本光源</h3><p>THREE.AmbientLight：基本光源，其颜色会应用到全局，且不会生成阴影；会将场景中物体均渲染为相同颜色。</p>
<p>THREE.Color对象：在为材质、灯光指定颜色时，可以使用字符串或者用THREE.Color对象，此时可通过直接修改THREE.Color类携带的方法来读取和修改内部颜色值。</p>
<h3 id="聚光灯光源"><a href="#聚光灯光源" class="headerlink" title="聚光灯光源"></a>聚光灯光源</h3><p>THREE.SpotLight:聚光灯光源，是最常用的光源之一，是一种具有锥形效果的光源，可与手电筒、灯塔的光相对比，其光具有方向与角度。其常用属性如下：</p>
<p>angle:角度，光源发射出的光束的宽度。castShadow：投影，设置为true时，该光源会产生阴影。</p>
<p>color：光源的颜色。decay：衰减，光源强度随着离开光源的距离而衰减的速度。</p>
<p>distance：光源照射的距离。intensity：光源照射的强度。</p>
<p>position：光源所在的位置。penumbra：半影区，该属性设置聚光灯的追星照明区域在其边缘附近的平滑衰减速度。</p>
<p>power：功率。target:目标。将spotlight光源指向场景中的特定对象或位置。visible：光源开关。</p>
<p>当光源的shadow属性设置为enable时，可通过下面属性来调整阴影的特性。</p>
<p>shadow.bias：阴影偏移，用于设置阴影的位置；shadow.camera.far：投影远点，设置到距离光源的哪一个位置可以生成阴影。</p>
<p>shadow.camera.fov：投影视场，用于生成阴影的视场大小。shdow.camera.near：投影近点。</p>
<p>shadow.mapSize.width和shadow.mapSize.height：阴影映射面积与映射高度。shadow.radius：半径。</p>
<h3 id="点光源"><a href="#点光源" class="headerlink" title="点光源"></a>点光源</h3><p>THREE.PointLight：点光源，是一种单点发光、照射所有方向的光源。其常用的属性如下：</p>
<p>color:颜色；distance：距离；intensity：光源照射的强度；position：位置。</p>
<p>visible：是否可见；decay：衰减。光源强度随着离开光源的距离而衰减的速度。power：功率。</p>
<p>同样，点光源可以像聚光灯光源一样启用阴影并设置其属性。THREE.PointLight同样使用摄像机来决定如何绘制阴影，所以也可以使用辅助类THREE.CameraHelper来展示场景中哪些部分被光源的摄像机所覆盖；使用THREE.PointLightHelper来展示点光源的光线所照射的位置。</p>
<h3 id="平行光源"><a href="#平行光源" class="headerlink" title="平行光源"></a>平行光源</h3><p>THREE.DirectionalLight：平行光，该类型可以看作是距离很远的光，它发出的光线都是相互平行的。且平行光不像聚光灯那样离目标越远越暗淡，被平行光照亮的区域接受到的光强是一样的。且由于所有的光线是平行的，所以不会有光锥，而是一个立方体区域。</p>
<h2 id="特殊光源"><a href="#特殊光源" class="headerlink" title="特殊光源"></a>特殊光源</h2><h3 id="半球光光源"><a href="#半球光光源" class="headerlink" title="半球光光源"></a>半球光光源</h3><p>THREE.HemisphereLight：半球光光源可以模拟出更自然的户外光照效果，考虑了天空和地面的折射。</p>
<h3 id="区域光光源"><a href="#区域光光源" class="headerlink" title="区域光光源"></a>区域光光源</h3><p>THREE.AreaLight：可定义一个长方形的发光区域。</p>
<h3 id="镜头光晕"><a href="#镜头光晕" class="headerlink" title="镜头光晕"></a>镜头光晕</h3><p>通过实例化THREE.LensFlare对象来创建镜头光晕。该对象可以接受以下参数：</p>
<p>texture：纹理；size：尺寸；distance：距离；blending：混合；color：颜色；opacity：不透明度。</p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>AmbientLight基本光源的颜色可附加到场景中的每一个颜色中，通常用于柔化生硬的颜色与阴影；PointLight点光源会朝所有方向发射光线，不能用于创建阴影；SpotLight聚光灯光源类似于手电筒，有一个锥形的光束，可配置随距离增大而逐渐变弱，且可生成阴影；DirectionalLight光源，这个光源相当于远光的效果，其光强不会改变。类似于太阳光；</p>
<p>THREE.HemisphereLight：半球光光源可以模拟出更自然的户外光照效果，考虑了天空和地面的折射。</p>
<p>THREE.AreaLight：不从单点发射光线，而是从一个很大的区域发射光线。</p>
<h1 id="材质"><a href="#材质" class="headerlink" title="材质"></a>材质</h1><p>材质结合THREE.Geometry就可以构成THREE.Mesh对象，材质就像物体的皮肤，决定了几何体的外表。Three.js提供了一个材质基类THREE.Material，它列出了所有的共有属性。</p>
<h2 id="属性"><a href="#属性" class="headerlink" title="属性"></a>属性</h2><h3 id="基础属性"><a href="#基础属性" class="headerlink" title="基础属性"></a>基础属性</h3><p>id：标识符，用于识别材质，并在材质创建时赋值；uuid：生成的唯一ID。</p>
<p>name：名称。opacity：不透明度。transparent：定义是否透明，定义为true时会使用指定的opacity渲染物体。</p>
<p>overdraw：过度描绘。visible：是否可见。side：侧面，通过该属性，可定义几何体的哪一面应用材质，默认值为前面。</p>
<p>needUpdata：是否需要实时更新材质。colorWrite：是否输出颜色。</p>
<p>flatShading：平面着色，该属性控制物体表面法线的生成方式，从而影响光照效果。</p>
<p>lights：控制物体表面是否接受光照。premultipliedAlpha：该属性控制半透明表面的颜色混合方式。</p>
<p>dithering：抖动，控制是否启用颜色抖动模式。shadowSide：投影面，控制物体的哪个面投射阴影。</p>
<p>vertexColors：顶点颜色。你可为物体的每一个顶点指定特有的颜色。fog：雾，控制材质是否收到雾的影响。</p>
<h3 id="融合属性"><a href="#融合属性" class="headerlink" title="融合属性"></a>融合属性</h3><p>材质有几个与融合相关的一般属性，其决定我们渲染的颜色如何与他们后面的颜色交互。</p>
<p>blending：融合，该属性决定物体上的材质如何与背景融合，默认情况下只显示材质的上层。</p>
<p>blendSrc：融合源，创建自定义的融合模式，该属性定义物体如何与背景相融合。</p>
<p>blendSrcAlpha:融合源透明度。blendDst：融合目标，定义融合时如何使用背景。</p>
<p>blendDstAlpha：融合目标透明度。blendEquation：融合公式，默认为相加。</p>
<h3 id="高级属性"><a href="#高级属性" class="headerlink" title="高级属性"></a>高级属性</h3><p>这些属性与WebGL内部如何工作相关。</p>
<p>depthTest、depthWrite、depthFunc、alphatest、precision。</p>
<h2 id="网格材质"><a href="#网格材质" class="headerlink" title="网格材质"></a>网格材质</h2><h3 id="MeshBasicMaterial"><a href="#MeshBasicMaterial" class="headerlink" title="MeshBasicMaterial"></a>MeshBasicMaterial</h3><p>MeshBasicMaterial是一种非常简单的材质，该材质不考虑场景中光照的影响，使用该材质的网格会被渲染成简单的平面多边形，而且可以显示几何体的线框。</p>
<h3 id="MeshDepthMaterial"><a href="#MeshDepthMaterial" class="headerlink" title="MeshDepthMaterial"></a>MeshDepthMaterial</h3><p>MeshDepthMaterial：使用该材质的物体，其外观不是由光照或者某个材质属性决定的，而是由物体到摄像机的距离决定的。可以将该材质与其他材质结合使用，这样就可以容易地创建出逐渐消失的效果。</p>
<p>一般MeshDepthMaterial会与另一种颜色材质相融合后使用。</p>
<h3 id="MeshNormalMaterial"><a href="#MeshNormalMaterial" class="headerlink" title="MeshNormalMaterial"></a>MeshNormalMaterial</h3><p>MeshNormalMaterial：使用该材质时，每一面的颜色是由从该面向外指的法向量计算得到的，所谓法向量是指与面垂直的向量。法向量通常用于决定光的反射，有助于将纹理映射到三维模型，并提供有关如何计算光照、阴影、表面像素着色的信息。</p>
<h2 id="高级材质"><a href="#高级材质" class="headerlink" title="高级材质"></a>高级材质</h2><p>Three.js提供了两种高级材质MeshPhongMaterial与MeshLambertMaterial，他们会对光源做出反应，并可以分别创建光亮的材质与暗淡的材质。</p>
<h3 id="MeshPhongMaterial"><a href="#MeshPhongMaterial" class="headerlink" title="MeshPhongMaterial"></a>MeshPhongMaterial</h3><p>MeshPhongMaterial用于创建暗淡1的并不光亮的表面。</p>
<p>color：材质的环境色；emissive：自发光，材质自发光的颜色，该属性虽然不会让使用它的物体变成光源，但会使物体的颜色不受其他光源的影响。</p>
<h3 id="MeshLambertMaterial"><a href="#MeshLambertMaterial" class="headerlink" title="MeshLambertMaterial"></a>MeshLambertMaterial</h3><p>一般用于创建光亮的材质。同样有color、emissive，还有specular：高光颜色，shiness：高光度。</p>
<p>还有MeshStandardtMaterial与MeshPhysicalMaterial。两者均用于反光相关功能实现。</p>
<h3 id="ShaderMaterial"><a href="#ShaderMaterial" class="headerlink" title="ShaderMaterial"></a>ShaderMaterial</h3><p>ShaderMaterial是最常用也最复杂的材质，通过它我们用自己定制的着色器，直接在WEBGL的环境下运行，着色器将屏幕中的JS网格转换为屏幕上的像素，利用这些自定义的着色器，可明确指定对象如何渲染，以及更改Three.js中默认值。</p>
<p>ShaderMaterial中最重要部分是其两个着色器：</p>
<p>顶点着色器vertexShader，会在几何体的每一个顶点上执行，可利用该着色器通过改变顶点的位置来对几何体进行变换。</p>
<p>片元着色器fragmentShader会在几何体的每一个片段上执行，会返回这个特定片段应该显示的颜色。</p>
<h2 id="线性几何体材质"><a href="#线性几何体材质" class="headerlink" title="线性几何体材质"></a>线性几何体材质</h2><p>LineBasicMaterial用于线段的基础材质</p>
<p>LineDashedMaterial可通过指定虚线和空白间隙的长度来创建出虚线效果。</p>

    </div>
    
    
    
    
    <div>
      
        <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;">-------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------</div>
    
</div>

      
    </div>
        <div class="reward-container">
  <div>坚持原创技术分享，您的支持将鼓励我继续创作！</div>
  <button onclick="var qr = document.getElementById('qr'); qr.style.display = (qr.style.display === 'none') ? 'block' : 'none';">
    打赏
  </button>
  <div id="qr" style="display: none;">
      
      <div style="display: inline-block;">
        <img src="/images/alipay.png" alt="Li Yudong 支付宝">
        <p>支付宝</p>
      </div>

  </div>
</div>

        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>Li Yudong
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="http://example.com/2021/09/16/webgl/three.js%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97/" title="three.js初学">http://example.com/2021/09/16/webgl/three.js开发指南/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

    
      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/three-js/" rel="tag"># three.js</a>
          </div>
    
        

    
        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2021/09/15/webgl/webgl%E6%96%B0%E6%89%8B%E6%95%99%E7%A8%8B/" rel="prev" title="webgl编程指南初学">
      <i class="fa fa-chevron-left"></i> webgl编程指南初学
    </a></div>
      <div class="post-nav-item">
    <a href="/2021/09/23/webgl/three.js%E5%87%A0%E4%BD%95%E4%BD%93/" rel="next" title="three.js几何体">
      three.js几何体 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#概述"><span class="nav-number">1.</span> <span class="nav-text">概述</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#初始化场景"><span class="nav-number">1.1.</span> <span class="nav-text">初始化场景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#材质、光源与阴影"><span class="nav-number">1.2.</span> <span class="nav-text">材质、光源与阴影</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#动画"><span class="nav-number">1.3.</span> <span class="nav-text">动画</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#requestAnimationFrame"><span class="nav-number">1.3.1.</span> <span class="nav-text">requestAnimationFrame</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#基本组件"><span class="nav-number">2.</span> <span class="nav-text">基本组件</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#场景"><span class="nav-number">2.1.</span> <span class="nav-text">场景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#物体"><span class="nav-number">2.2.</span> <span class="nav-text">物体</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#摄像机"><span class="nav-number">2.3.</span> <span class="nav-text">摄像机</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#光源"><span class="nav-number">3.</span> <span class="nav-text">光源</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#基础光源"><span class="nav-number">3.1.</span> <span class="nav-text">基础光源</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#基本光源"><span class="nav-number">3.1.1.</span> <span class="nav-text">基本光源</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#聚光灯光源"><span class="nav-number">3.1.2.</span> <span class="nav-text">聚光灯光源</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#点光源"><span class="nav-number">3.1.3.</span> <span class="nav-text">点光源</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#平行光源"><span class="nav-number">3.1.4.</span> <span class="nav-text">平行光源</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#特殊光源"><span class="nav-number">3.2.</span> <span class="nav-text">特殊光源</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#半球光光源"><span class="nav-number">3.2.1.</span> <span class="nav-text">半球光光源</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#区域光光源"><span class="nav-number">3.2.2.</span> <span class="nav-text">区域光光源</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#镜头光晕"><span class="nav-number">3.2.3.</span> <span class="nav-text">镜头光晕</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#总结"><span class="nav-number">3.3.</span> <span class="nav-text">总结</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#材质"><span class="nav-number">4.</span> <span class="nav-text">材质</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#属性"><span class="nav-number">4.1.</span> <span class="nav-text">属性</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#基础属性"><span class="nav-number">4.1.1.</span> <span class="nav-text">基础属性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#融合属性"><span class="nav-number">4.1.2.</span> <span class="nav-text">融合属性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#高级属性"><span class="nav-number">4.1.3.</span> <span class="nav-text">高级属性</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#网格材质"><span class="nav-number">4.2.</span> <span class="nav-text">网格材质</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#MeshBasicMaterial"><span class="nav-number">4.2.1.</span> <span class="nav-text">MeshBasicMaterial</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#MeshDepthMaterial"><span class="nav-number">4.2.2.</span> <span class="nav-text">MeshDepthMaterial</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#MeshNormalMaterial"><span class="nav-number">4.2.3.</span> <span class="nav-text">MeshNormalMaterial</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#高级材质"><span class="nav-number">4.3.</span> <span class="nav-text">高级材质</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#MeshPhongMaterial"><span class="nav-number">4.3.1.</span> <span class="nav-text">MeshPhongMaterial</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#MeshLambertMaterial"><span class="nav-number">4.3.2.</span> <span class="nav-text">MeshLambertMaterial</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ShaderMaterial"><span class="nav-number">4.3.3.</span> <span class="nav-text">ShaderMaterial</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#线性几何体材质"><span class="nav-number">4.4.</span> <span class="nav-text">线性几何体材质</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Li Yudong"
      src="/images/author.jpg">
  <p class="site-author-name" itemprop="name">Li Yudong</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">95</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">14</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">18</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/tiarmor1" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;tiarmor1" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:1157019137@qq.com" title="E-Mail → mailto:1157019137@qq.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
  </div>
  <div class="cc-license motion-element" itemprop="license">
    <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" class="cc-opacity" rel="noopener" target="_blank"><img src="/images/cc-by-nc-sa.svg" alt="Creative Commons"></a>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 2020 – 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Li Yudong</span>
</div>

        








      </div>
    </footer>
  </div>

  
  
  <script color='0,0,0' opacity='0.5' zIndex='-1' count='150' src="/lib1/canvas-nest/canvas-nest.min.js"></script>
  <script src="/lib1/anime.min.js"></script>
  <script src="/lib1/velocity/velocity.min.js"></script>
  <script src="/lib1/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  




  
<script src="/js/local-search.js"></script>













  

  

  
   <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas> 
   <script type="text/javascript" src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script> 
   <script type="text/javascript" src="/js/fireworks.js"></script>
  
</body>
</html>

